package com.chengyi.serialport.demo.activity

import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
import android.os.Bundle
import android.text.TextUtils
import android.view.MotionEvent
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.databinding.library.baseAdapters.BR
import androidx.lifecycle.ViewModelProvider
import com.chengyi.serialport.demo.gson.toJsonObject
import com.google.gson.JsonObject
import com.hjq.toast.Toaster
import com.qmuiteam.qmui.arch.QMUIActivity
import com.qmuiteam.qmui.arch.QMUISwipeBackActivityManager
import com.qmuiteam.qmui.util.QMUIKeyboardHelper
import com.qmuiteam.qmui.widget.QMUITopBar
import com.qmuiteam.qmui.widget.QMUITopBarLayout
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import com.wyj.controller.UIController
import com.wyj.databinding.BaseViewModel
import com.wyj.utils.AppConfig
import com.wyj.utils.QMUIDialogHelper
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.reflect.ParameterizedType


abstract class BaseActivity<V : ViewDataBinding, VM : BaseViewModel> : QMUIActivity(),UIController.IActivityLauncher {
    protected lateinit var binding: V
    protected val vm: VM by lazy {
        getViewModel()
    }
    private var dialog: QMUITipDialog? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        vm.activityLauncher = UIController.createActivityLauncher({ if (isFinishing || isDestroyed) null else this }, this::registerForActivityResult)
        if (!getBundleExtras(intent?.extras?.toJsonObject())) {
            Toaster.show("获取数据失败,请重新打开")
            finish()
            return
        }
        beforeContentView()
        lifecycle.addObserver(vm)
        initViewDataBinding()
        registerUIChangeLiveDataCallBack()
        setContentView(binding.root)
        initViews()
    }

    override fun getCurrentContext(): Context? {
        return vm.activityLauncher.getCurrentContext()
    }

    override fun launch(intent: Intent, callback: ((resultCode: Int, data: Intent?) -> Unit)?) {
        vm.activityLauncher.launch(intent, callback)
    }

    protected open fun registerUIChangeLiveDataCallBack() {
        EventBus.getDefault().register(this)
        //加载对话框显示
        vm.uiChangeLiveData.loadingDialogEvent.observe(this) {
            when (it) {
                true -> {
                    if (dialog == null) {
                        dialog = QMUIDialogHelper.createLoadingDialog(this)
                        dialog?.show()
                    }
                }

                false -> {
                    if (dialog?.isShowing == true) {
                        dialog?.dismiss()
                    }
                    dialog = null
                }
            }
        }
        vm.uiChangeLiveData.finishEvent.observe(this) {
            finish()
        }
        vm.uiChangeLiveData.screenOrientation.value?.let(this::setRequestedOrientation)
        vm.uiChangeLiveData.screenOrientation.observe(this) {
            requestedOrientation = it ?: return@observe
        }
        vm.uiChangeLiveData.binding.value = binding
    }

    private fun initViewDataBinding() {
        binding = DataBindingUtil.inflate(layoutInflater, getLayoutRes(), null, false)
        binding.lifecycleOwner = this
        binding.setVariable(variableId, vm)
        binding.executePendingBindings()
    }

    protected open fun getViewModel(): VM {
        return ViewModelProvider(this).get(
            try {
                (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[1] as Class<VM>
            } catch (e: Exception) {
                BaseViewModel::class.java
            }
        ) as VM
    }

    protected abstract fun getLayoutRes(): Int
    protected open fun getBundleExtras(bundle: JsonObject?): Boolean {
        return true
    }

    protected open val variableId: Int = BR.viewModel
    protected open fun beforeContentView() {
    }

    protected fun initBar(topBarView: QMUITopBar): QMUITopBar {
        topBarView.setBackgroundAlpha(0)
        topBarView.setTitle(title?.toString()).setEllipsize(TextUtils.TruncateAt.END)
        if (QMUISwipeBackActivityManager.getInstance().canSwipeBack(this) && canDragBack()) {
            topBarView.addLeftBackImageButton()?.setOnClickListener {
                finish()
            }
        }
        return topBarView
    }

    protected fun initBar(topBarView: QMUITopBarLayout): QMUITopBarLayout {
        topBarView.setTitle(title?.toString()).setEllipsize(TextUtils.TruncateAt.END)
        if (QMUISwipeBackActivityManager.getInstance().canSwipeBack(this) && canDragBack()) {
            topBarView.addLeftBackImageButton()?.setOnClickListener {
                finish()
            }
        }
        return topBarView
    }

    final override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
        lifecycle.removeObserver(vm)
        val binding = if (this::binding.isInitialized) binding else null
        onDestroy(binding)
        binding?.unbind()
        vm.uiChangeLiveData.binding.value = null
    }

    protected open fun onDestroy(binding: V?) {

    }

    protected open fun initViews() {

    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setIntent(intent)
    }

    override fun onPause() {
        QMUIKeyboardHelper.hideKeyboard(currentFocus)
        super.onPause()
    }

    //点击空白处隐藏软键盘，提升用户体验
    override fun dispatchTouchEvent(e: MotionEvent?): Boolean {
        if (e?.action == MotionEvent.ACTION_DOWN) {
            QMUIKeyboardHelper.hideKeyboard(currentFocus)
        }
        return super.dispatchTouchEvent(e)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onExitApplication(e: AppConfig.EVENT_CODE.EXIT_APPLICATION) {
        finish()
    }
}